package com.eurobcoin.controller;

import java.util.Locale;

import javax.validation.Valid;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.eurobcoin.filipides.model.SignupForm;
import com.eurobcoin.helper.PasswdHelper;
import com.eurobcoin.invite.InviteManager;
import com.eurobcoin.manager.DAOManager;
import com.eurobcoin.user.UserConst;
import com.eurobcoin.user.UserManager;
import com.eurobcoin.user.UserModel;

@Controller
@RequestMapping("/signup")
public class SignupUserController {

	public static final String SIGNUP_VIEW = "signup/signup";
	public static final String SUCCESS_VIEW = "signup/success";
	
	private static final String INDEX_REDIRECT = "redirect:/index.html";
	
	private static final String SIGNUP_USER_ROLE = "N_USER";
	
	@Autowired
	private DAOManager daoManager;
	
	@Autowired
	private InviteManager inviteManager;
	
	@Autowired
	private UserManager userManager;
	
	private ReloadableResourceBundleMessageSource messageSource;
	
	@Autowired
	public void setMessageSource(ReloadableResourceBundleMessageSource messageSource) {
		this.messageSource = messageSource;
	}
	
	@RequestMapping(value="/do_signup.html", method=RequestMethod.POST)
	public ModelAndView signupUser(
			@Valid @ModelAttribute(value="signupForm") SignupForm signupForm,
			BindingResult result) throws Exception {
		
		Locale locale = LocaleContextHolder.getLocale(); 
		
		ModelAndView ret = null;
		
		if(result.hasErrors()) {
			
			ret = new ModelAndView(SIGNUP_VIEW);
			
		} else {
			
			SqlSession sqlSession = this.daoManager.openSession();
			boolean commit = false;
			
			if(!signupForm.getEmail().endsWith("@gmail.com")) {
				
				signupForm.setError(true);
				signupForm.setErrorMsg(messageSource.getMessage(
						"signup.error.notGmail", null, locale));
				
				ret = new ModelAndView(SIGNUP_VIEW);
				
			} else {
				
				UserModel user = this.userManager.getUserByEmail(sqlSession, signupForm.getEmail());
				
				if(user != null) {
					
					signupForm.setError(true);
					signupForm.setErrorMsg(messageSource.getMessage(
							"validation.error.email.duplicated", null, locale));
					
					ret = new ModelAndView(SIGNUP_VIEW);
					
				} else {
					
					String username = this.userManager.generateUniqueUsername(sqlSession);
					int rol = this.userManager.getRoleIdByName(sqlSession, SIGNUP_USER_ROLE);
					int invitingUserId = this.inviteManager.getInvitingUserByHash(sqlSession, signupForm.getInviteHash());
					
					int retCode = this.userManager.saveUser(
							sqlSession, 
							signupForm.getSalt(), 
							signupForm.getHashedPassword(), 
							username, 
							signupForm.getEmail(), 
							false, 
							locale.getLanguage(), 
							rol,
							invitingUserId);
					
					if(retCode == UserConst.USR_SAVE_OK) {
						// delete invitation
						this.inviteManager.deleteInvite(sqlSession, signupForm.getInviteHash());
						
						ret = new ModelAndView(SUCCESS_VIEW);
						
						ret.addObject("username", username);
						ret.addObject("email", signupForm.getEmail());
						
						commit = true;
					}
					
				}
				
			}
			
			if(commit)
				sqlSession.commit();
			
			sqlSession.close();
			
		}
		
		return ret;
		
	}
	
	@RequestMapping(value="/signup.html", method=RequestMethod.GET)
	public ModelAndView doSignupForm(
			@RequestParam("hash") String hash,
			@ModelAttribute(value="signupForm") SignupForm signupForm) {
		
		ModelAndView ret = null;
		
		SqlSession sqlSession = this.daoManager.openSession();
		
		boolean validInvite = this.inviteManager.isValidInvite(sqlSession, hash);
		
		if(validInvite) {
			ret = new ModelAndView(SIGNUP_VIEW);
			signupForm.setInviteHash(hash);
			
			// generar sal para la contraseña
			String salt = PasswdHelper.generateSalt();
			signupForm.setSalt(salt);
		} else {
			ret = new ModelAndView(INDEX_REDIRECT);
		}
		
		sqlSession.close();
		
		return ret;
		
	}
	
}
